package com.usdt.web.controller.cp.activity;

import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.excel.write.metadata.fill.FillWrapper;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.usdt.common.core.domain.R;
import com.usdt.system.domain.req.ActivityImgReqVO;
import com.usdt.system.domain.req.ActivityListReqVO;
import com.usdt.system.domain.req.ActivityListV2ReqVO;
import com.usdt.system.domain.req.ActivityReqVO;
import com.usdt.system.domain.req.ActivitySignUpReqVO;
import com.usdt.system.domain.req.ActivitySummaryReqVO;
import com.usdt.system.domain.req.ActivityUpdateStatusReqVO;
import com.usdt.system.domain.req.ActivitylistExportReqVO;
import com.usdt.system.domain.resp.ActivityCalendarV1Resp;
import com.usdt.system.domain.resp.ActivityRespVO;
import com.usdt.system.dto.cp.ActivityCustomerExcelDTO;
import com.usdt.system.dto.cp.ActivityDetailExcelDTO;
import com.usdt.system.dto.cp.ActivityListExcelDTO;
import com.usdt.system.dto.cp.ActivityPointsExcelDTO;
import com.usdt.system.dto.cp.WeeklyScheduleDTO;
import com.usdt.system.service.cp.ActivityService;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;

@RestController
@Slf4j
@RequestMapping("/activity")
@Tag(name = "活动接口")
public class ActivityController {
	
	@Autowired
	private ActivityService activityService; 

    @PostMapping("/insert")
    @Operation(summary ="新增")
    public R<Integer> insert(@RequestBody ActivityReqVO vo) {
    	
    	return R.ok(activityService.insert(vo));
    }
    
    @PostMapping("/insertList")
    @Operation(summary ="批量新增")
    public R<Object> insertList(@RequestBody ActivityListReqVO vo) {
    	
    	activityService.insertList(vo);
    	return R.ok();
    }
    
    @PostMapping("/insertList/v2")
    @Operation(summary ="批量新增-新")
    public R<Object> insertListV2(@RequestBody ActivityListV2ReqVO vo) {
    	
    	activityService.insertListV2(vo);
    	return R.ok();
    }
    
    @GetMapping("/detail/{id}")
    @Operation(summary ="详情")
    public R<ActivityRespVO> insert(@Schema(description = "活动id")@PathVariable(value = "id", required = true) Integer id) {
    	
    	return R.ok(activityService.detail(id));
    }
    
    @GetMapping("/count")
    @Operation(summary ="根据时间范围查询项目数目")
    public R<Map<String,Integer>> count(
    		@Schema(description = "开始日期（yyyy-MM-dd）")@RequestParam(value = "startDate", required = false) String startDate,
    		@Schema(description = "结束日期（yyyy-MM-dd）")@RequestParam(value = "endDate", required = false) String endDate
    		) {
    	Map<String,Integer> map = new HashMap<String,Integer>();
    	map.put("count", activityService.count(startDate,endDate));
    	return R.ok(map);
    }
    
    @GetMapping("/list")
    @Operation(summary ="列表")
    public R<IPage<ActivityRespVO>> list(
    		@Schema(description = "活动维度")@RequestParam(value = "activityCategory", required = false) Integer activityCategory,
    		@Schema(description = "活动类别")@RequestParam(value = "activityType", required = false) Integer activityType,
    		@Schema(description = "关键词")@RequestParam(value = "keyWord", required = false) String keyWord,
    		@Schema(description = "状态 1：已结束  2：已取消  3：待开始  4：进行中")@RequestParam(value = "activityStatus", required = false) Byte activityStatus,
    		//@Schema(description = "所属项目")@RequestParam(value = "deptId", required = false) String deptId,
    		@Schema(description = "开始日期（yyyy-MM-dd）")@RequestParam(value = "startDate", required = false) String startDate,
    		@Schema(description = "结束日期（yyyy-MM-dd）")@RequestParam(value = "endDate", required = false) String endDate,
    		@Schema(description = "页码")@RequestParam(value = "pageNum", required = false) Integer pageNum,
    		@Schema(description = "每页显示记录数")@RequestParam(value = "pageSize", required = false) Integer pageSize
    		) {
    	
    	return R.ok(activityService.list(activityCategory,activityType,keyWord,activityStatus,startDate,endDate,pageNum,pageSize));
    }
    
    @GetMapping("/calendar/list")
    @Operation(summary ="列表-日历")
    public R<ActivityCalendarV1Resp> calendarList(
    		@Schema(description = "开始日期（yyyy-MM-dd）")@RequestParam(value = "startDate", required = true) String startDate,
    		@Schema(description = "结束日期（yyyy-MM-dd）")@RequestParam(value = "endDate", required = true) String endDate
    		) {
    	
    	return R.ok(activityService.calendarList(startDate,endDate));
    }
    
    @PostMapping("/update")
    @Operation(summary ="修改")
    public R<Integer> update(@RequestBody ActivityReqVO vo) {
    	
    	return R.ok(activityService.update(vo));
    }
    
    @PostMapping("/updateStatus")
	@Operation(summary = "更新状态")
	public R<Integer> updateStatus(@RequestBody ActivityUpdateStatusReqVO vo) {
    	
    	return R.ok(activityService.updateStatus(vo));
    }
    
    @PostMapping("/signUp")
    @Operation(summary ="报名")
    public R<Integer> signUp(@RequestBody ActivitySignUpReqVO vo) {
    	
    	return R.ok(activityService.signUp(vo));
    }
    
    @PostMapping("/img")
    @Operation(summary ="图片/视频")
    public R<Integer> img(@RequestBody ActivityImgReqVO vo) {
    	if(null==vo || null==vo.getId() || null==vo.getType()) {
    		return R.ok(0);
    	}
    	return R.ok(activityService.img(vo));
    }
    
	/*@PostMapping("/video")
	@Operation(summary ="视频")
	public R<Integer> video(@RequestBody ActivityImgReqVO vo) {
		
		return R.ok(activityService.video(vo));
	}*/
    
    @PostMapping("/summary")
    @Operation(summary ="总结")
    public R<Integer> summary(@RequestBody ActivitySummaryReqVO vo) {
    	if(null==vo || null==vo.getId()) {
    		return R.ok(0);
    	}
    	
    	return R.ok(activityService.summary(vo));
    }
    
    @PostMapping("/list/export")
    @Operation(summary ="导出-列表")
    public void listExport(
    		HttpServletResponse response,
    		@RequestBody ActivitylistExportReqVO vo) throws IOException {
    	
    	List<ActivityListExcelDTO> list = activityService.listExport(vo);
    	exportActivityExcel(response,list,ActivityListExcelDTO.class,"活动信息表","活动信息");
    }
    
    @PostMapping("/calendar/export")
    @Operation(summary ="导出-日历")
    public void calendarListExport(
    		HttpServletResponse response,
    		@RequestBody ActivitylistExportReqVO vo) throws IOException {
    	
    	WeeklyScheduleDTO dto = activityService.calendarListExport(vo);
    	exportSchedule(response,"excel/activity-calendar-temp.xlsx",dto);
    }
    
	/*    @GetMapping("/calendar/export/test")
	@Operation(summary ="导出-日历")
	public void calendarListExporttest(
			HttpServletResponse response) throws IOException {
		ActivitylistExportReqVO vo = new ActivitylistExportReqVO();
		vo.setStartDate("2025-08-25");
		vo.setEndDate("2025-08-31");
		
		
		WeeklyScheduleDTO dto = activityService.calendarListExport(vo);
		exportSchedule(response,"excel/activity-calendar-temp.xlsx",dto);
	}*/
    
    public static void exportSchedule(HttpServletResponse response,String path, WeeklyScheduleDTO data) throws IOException {
        // 1. 模板路径（放在resources目录下）
		/*String templatePath = ActivityController.class.getClassLoader()
		        .getResource(path).getPath();*/
        InputStream resourceAsStream = ActivityController.class.getClassLoader()
                .getResourceAsStream(path);
        
        // 1. 设置响应头（关键：避免中文乱码、指定文件类型）
    	response.addHeader("Pargam", "no-cache");
    	response.addHeader("Cache-Control", "no-cache");
    	response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        //response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); // Excel 2007+格式
    	//response.setContentType("application/octet-stream;charset=UTF-8"); // Excel 2007+格式
        response.setCharacterEncoding("utf-8");
        // 文件名编码：使用URLEncoder避免中文乱码，替换“+”为“%20”（浏览器兼容）
        String fileName = URLEncoder.encode("活动日历列表.xlsx", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + fileName + ".xlsx");
        
        SheetWriteHandler sheetWriteHandler = new SheetWriteHandler() {
        	@Override
        	public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
        		Sheet sheet = writeSheetHolder.getSheet();
        		sheet.addMergedRegion(new CellRangeAddress(data.getFirstRow(),data.getLastRow(),9,11));
        	}
		};

        // 2. 导出配置
        ExcelWriter writer = EasyExcel.write(response.getOutputStream())
                .withTemplate(resourceAsStream)
                .registerWriteHandler(sheetWriteHandler)
				/*.registerWriteHandler(
						new AutoColumnWidthHandler()
					    .minWidth(5 * 256)    // 5个字符宽度
					    .maxWidth(80 * 256)   // 80个字符宽度
					    .scaleFactor(1.2f))*///自定义：自动调整所有列宽
                .build();

        WriteSheet sheet = EasyExcel.writerSheet().build();
        FillConfig fillConfig = FillConfig.builder()
                .forceNewRow(Boolean.TRUE) // 可选：是否强制创建新行
                .build();
        FillConfig fillConfig2 = FillConfig.builder()
        		//.forceNewRow(Boolean.TRUE) // 可选：是否强制创建新行
        		.build();

        // 3. 填充数据
        writer.fill(data, sheet);
		writer.fill(new FillWrapper("week1", data.getWeek1().getV3List()),
				fillConfig,
				sheet);
		writer.fill(new FillWrapper("week2", data.getWeek2().getV3List()), 
				fillConfig2,
		           sheet);
		writer.fill(new FillWrapper("week3", data.getWeek3().getV3List()), 
				fillConfig2,
		           sheet);
		writer.fill(new FillWrapper("week4", data.getWeek4().getV3List()),
				fillConfig2,
		           sheet);
		writer.fill(new FillWrapper("week5", data.getWeek5().getV3List()),
				fillConfig,
		           sheet);
		writer.fill(new FillWrapper("week6", data.getWeek6().getV3List()), 
				fillConfig2,
		           sheet);
		writer.fill(new FillWrapper("week7", data.getWeek7().getV3List()),
				fillConfig2,
		           sheet);
		writer.fill(new FillWrapper("week8", data.getWeek8().getV3List()),
				fillConfig2,
				sheet);
		
        // 4. 关闭流
        writer.finish();
    }
    
    @PostMapping("/detail/export")
    @Operation(summary ="详情-导出")
    public void detailExport(
    		HttpServletResponse response,
    		@RequestBody ActivitylistExportReqVO vo) throws IOException {
    	
    	//sheet1 活动详情
    	List<ActivityDetailExcelDTO> list = activityService.detailExport(vo);
    	//exportActivityExcel(response,list,ActivityDetailExcelDTO.class,"活动详情表","活动信息");
    	
    	//sheet2 参与人员
    	List<ActivityCustomerExcelDTO> list2 = activityService.customerExport(vo);
    	ActivityRespVO detail = activityService.detail(vo.getId());
    	String title = detail.getName()+"("+detail.getActivityTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"))+")";
    	//exportActivityExcel2(response,list,ActivityCustomerExcelDTO.class,"活动参与人员表","活动参与人员",title);
    	
    	//导出

        // 1. 设置响应头（关键：避免中文乱码、指定文件类型）
    	response.addHeader("Pargam", "no-cache");
    	response.addHeader("Cache-Control", "no-cache");
    	response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 文件名编码：使用URLEncoder避免中文乱码，替换“+”为“%20”（浏览器兼容）
        String fileName = URLEncoder.encode("活动详情表", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + fileName + ".xlsx");

        ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream())
        		.build();
        
        WriteSheet sheet = EasyExcel.writerSheet(0, "活动信息")
        		.relativeHeadRowIndex(1) 
        		.head(ActivityDetailExcelDTO.class)
        		.registerWriteHandler(
						new SheetWriteHandler() {
				            @Override
				            public void afterSheetCreate(WriteWorkbookHolder holder, WriteSheetHolder sheetHolder) {
				                Sheet sheet = sheetHolder.getSheet();
				                Workbook workbook = holder.getWorkbook();
				                
								CellStyle style = workbook.createCellStyle();
								//style.setLocked(true); // 设置单元格为锁定状态
								style.setAlignment(HorizontalAlignment.CENTER); // 设置右对齐
								//背景灰色
								style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
								style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());//new Color(192, 192, 192)
								
								Row row = sheet.createRow(0);// 创建索引0的空白行
								//row.setHeight((short)52.2);
			                    Cell cell = row.createCell(0);
				    			cell.setCellValue(title);
				    			cell.setCellStyle(style);
				    			
				                sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 1));
				            }
				        })
        		.build();
        
        WriteSheet sheet1 = EasyExcel.writerSheet(1, "活动报名人员")
			        		.relativeHeadRowIndex(1) 
			        		.head(ActivityCustomerExcelDTO.class)
			        		.registerWriteHandler(
		    						new SheetWriteHandler() {
		    				            @Override
		    				            public void afterSheetCreate(WriteWorkbookHolder holder, WriteSheetHolder sheetHolder) {
		    				                Sheet sheet = sheetHolder.getSheet();
							                Workbook workbook = holder.getWorkbook();
							                
											CellStyle style = workbook.createCellStyle();
											//style.setLocked(true); // 设置单元格为锁定状态
											style.setAlignment(HorizontalAlignment.CENTER); // 设置右对齐
											//背景灰色
											style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
											style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());//new Color(192, 192, 192)
											
											Row row = sheet.createRow(0);// 创建索引0的空白行
											//row.setHeight((short)52.2);
						                    Cell cell = row.createCell(0);
		    				    			cell.setCellValue(title);
		    				    			cell.setCellStyle(style);
		    				    			
		    				                sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 1));
		    				            }
		    				        })
			        		.build();
        
        excelWriter.write(list, sheet);
    	excelWriter.write(list2, sheet1);
    	
    	// 5. 必须显式关闭流（重要！）
        excelWriter.finish();
    	
    }
    
    @PostMapping("/customer/export")
    @Operation(summary ="参与人-导出")
    public void customerExport(
    		HttpServletResponse response,
    		@RequestBody ActivitylistExportReqVO vo) throws IOException {
    	
    	List<ActivityCustomerExcelDTO> list = activityService.customerExport(vo);
    	ActivityRespVO detail = activityService.detail(vo.getId());
    	String title = detail.getName()+"("+detail.getActivityTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"))+")";
    	exportActivityExcel2(response,list,ActivityCustomerExcelDTO.class,"活动参与人员表","活动参与人员",title);
    }
    
    @PostMapping("/points/export")
    @Operation(summary ="积分统计-导出")
    public void pointsExport(
    		HttpServletResponse response,
    		@RequestBody ActivitylistExportReqVO vo) throws IOException {
    	
    	List<ActivityPointsExcelDTO> list = activityService.pointsExport(vo);
    	exportActivityExcel(response,list,ActivityPointsExcelDTO.class,"客户积分统计表","积分");
    }
    
    
    /**
     * 导出活动信息Excel（浏览器下载）
     * @param response HttpServletResponse（用于向浏览器输出Excel）
     * @param dataList 活动数据列表（需导出的实体类集合）
     * @throws IOException IO异常（如输出流关闭失败）
     */
    public void exportActivityExcel(HttpServletResponse response, List dataList, Class clazz
    		,String excelName,String sheetName) throws IOException {
        // 1. 设置响应头（关键：避免中文乱码、指定文件类型）
    	response.addHeader("Pargam", "no-cache");
    	response.addHeader("Cache-Control", "no-cache");
    	response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        //response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); // Excel 2007+格式
    	//response.setContentType("application/octet-stream;charset=UTF-8"); // Excel 2007+格式
        response.setCharacterEncoding("utf-8");
        // 文件名编码：使用URLEncoder避免中文乱码，替换“+”为“%20”（浏览器兼容）
        String fileName = URLEncoder.encode(excelName, "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + fileName + ".xlsx");

        // 2. 使用EasyExcel写入数据（try-with-resources自动关闭ExcelWriter）
        try (var excelWriter = EasyExcel.write(response.getOutputStream(), clazz).build()) {
            // 3. 构建Sheet（指定工作表名称，如“活动信息”）
            var sheet = EasyExcel.writerSheet(sheetName).build();
            // 4. 写入数据（将实体类列表映射为Excel行）
            excelWriter.write(dataList, sheet);
        }
    }
    public void exportActivityExcel2(HttpServletResponse response, List dataList, Class clazz
    		,String excelName,String sheetName,String title) throws IOException {
    	// 1. 设置响应头（关键：避免中文乱码、指定文件类型）
    	response.addHeader("Pargam", "no-cache");
    	response.addHeader("Cache-Control", "no-cache");
    	response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
    	//response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); // Excel 2007+格式
    	//response.setContentType("application/octet-stream;charset=UTF-8"); // Excel 2007+格式
    	response.setCharacterEncoding("utf-8");
    	// 文件名编码：使用URLEncoder避免中文乱码，替换“+”为“%20”（浏览器兼容）
    	String fileName = URLEncoder.encode(excelName, "UTF-8").replaceAll("\\+", "%20");
    	response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + fileName + ".xlsx");
    	
    	// 2. 使用EasyExcel写入数据（try-with-resources自动关闭ExcelWriter）
    	try (var excelWriter = EasyExcel.write(response.getOutputStream(), clazz).build()) {
    		// 3. 构建Sheet（指定工作表名称，如“活动信息”）
    		var sheet = EasyExcel
    				.writerSheet(sheetName)
    				.relativeHeadRowIndex(1) 
    				.registerWriteHandler(
    						new SheetWriteHandler() {
    				            @Override
    				            public void afterSheetCreate(WriteWorkbookHolder holder, WriteSheetHolder sheetHolder) {
    				                Sheet sheet = sheetHolder.getSheet();
					                Workbook workbook = holder.getWorkbook();
					                
									CellStyle style = workbook.createCellStyle();
									//style.setLocked(true); // 设置单元格为锁定状态
									style.setAlignment(HorizontalAlignment.CENTER); // 设置右对齐
									//背景灰色
									style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
									style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());//new Color(192, 192, 192)
									
									Row row = sheet.createRow(0);// 创建索引0的空白行
									//row.setHeight((short)52.2);
				                    Cell cell = row.createCell(0);
    				    			cell.setCellValue(title);
    				    			cell.setCellStyle(style);
    				    			
    				                sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 1));
    				            }
    				        })
    				.build();
    		// 4. 写入数据（将实体类列表映射为Excel行）
    		excelWriter.write(dataList, sheet);
    	}
    }
    
}
